// Copyright © 2023 Cisco Systems, Inc. and its affiliates.
// All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lsblk

import (
	"bytes"
	_ "embed"
	"testing"

	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/types"
)

//go:embed testdata/lsblk.ubuntu.json
var ubuntuLsblkJSONOutput []byte

//go:embed testdata/lsblk.alpine.json
var alpineLsblkJSONOutput []byte

// nolint:maintidx
func TestJSONFormat(t *testing.T) {
	tests := []struct {
		Name     string
		JSONData *bytes.Buffer
		Err      error

		ExpectedErrorMatcher    types.GomegaMatcher
		ExpectedBlockDeviceList []BlockDevice
	}{
		{
			Name:                    "Nil data",
			Err:                     nil,
			ExpectedErrorMatcher:    Not(HaveOccurred()),
			ExpectedBlockDeviceList: nil,
		},
		{
			Name:                 "JSON - Bytes as strings",
			JSONData:             bytes.NewBuffer(ubuntuLsblkJSONOutput),
			Err:                  nil,
			ExpectedErrorMatcher: Not(HaveOccurred()),
			ExpectedBlockDeviceList: []BlockDevice{
				{
					Name:                   "loop0",
					KernelName:             "loop0",
					Path:                   "/dev/loop0",
					MajorMinor:             "7:0",
					FSAvail:                0,
					FSSize:                 25690112,
					FSType:                 "squashfs",
					FSUsed:                 25690112,
					FSUsedPercent:          "100%",
					MountPoint:             "/snap/amazon-ssm-agent/6312",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "",
					PartitionTableType:     "",
					PartitionType:          "",
					PartitionLabel:         "",
					PartitionUUID:          "",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               true,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   25571328,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       128,
					Type:                   "loop",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     4096,
					DiscardMaxBytes:        4294966784,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "nvme0n1",
					KernelName:             "nvme0n1",
					Path:                   "/dev/nvme0n1",
					MajorMinor:             "259:0",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "341a00be-53e0-4393-91cf-ddf480890a27",
					PartitionTableType:     "gpt",
					PartitionType:          "",
					PartitionLabel:         "",
					PartitionUUID:          "",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "Amazon Elastic Block Store",
					Serial:                 "vol071a923e1421f847f",
					Size:                   8589934592,
					State:                  "live",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  4096,
					OptimalIO:              4096,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       31,
					Type:                   "disk",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "nvme.1d0f-766f6c3037316139323365313432316638343766-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001",
					Randomness:             false,
					ParentKernelName:       "",
					HostChannelTargetLun:   "",
					TransportType:          "nvme",
					Subsystems:             "block:nvme:pci",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "nvme0n1p1",
					KernelName:             "nvme0n1p1",
					Path:                   "/dev/nvme0n1p1",
					MajorMinor:             "259:1",
					FSAvail:                5202096128,
					FSSize:                 8132173824,
					FSType:                 "ext4",
					FSUsed:                 2913300480,
					FSUsedPercent:          "36%",
					MountPoint:             "/",
					Label:                  "cloudimg-rootfs",
					UUID:                   "db7f5fbc-cf4b-45ae-985d-11e4b2222934",
					PartitionTableUUID:     "341a00be-53e0-4393-91cf-ddf480890a27",
					PartitionTableType:     "gpt",
					PartitionType:          "0fc63daf-8483-4772-8e79-3d69d8477de4",
					PartitionLabel:         "",
					PartitionUUID:          "3a6867c7-ffb2-4db0-8246-7c2569317446",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   8473525760,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  4096,
					OptimalIO:              4096,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       31,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "nvme.1d0f-766f6c3037316139323365313432316638343766-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001",
					Randomness:             false,
					ParentKernelName:       "nvme0n1",
					HostChannelTargetLun:   "",
					TransportType:          "nvme",
					Subsystems:             "block:nvme:pci",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "nvme0n1p14",
					KernelName:             "nvme0n1p14",
					Path:                   "/dev/nvme0n1p14",
					MajorMinor:             "259:2",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "341a00be-53e0-4393-91cf-ddf480890a27",
					PartitionTableType:     "gpt",
					PartitionType:          "21686148-6449-6e6f-744e-656564454649",
					PartitionLabel:         "",
					PartitionUUID:          "53413f32-d40c-4d40-8384-c7221fa8e2c9",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   4194304,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  4096,
					OptimalIO:              4096,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       31,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "nvme.1d0f-766f6c3037316139323365313432316638343766-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001",
					Randomness:             false,
					ParentKernelName:       "nvme0n1",
					HostChannelTargetLun:   "",
					TransportType:          "nvme",
					Subsystems:             "block:nvme:pci",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "nvme0n1p15",
					KernelName:             "nvme0n1p15",
					Path:                   "/dev/nvme0n1p15",
					MajorMinor:             "259:3",
					FSAvail:                103092736,
					FSSize:                 109422592,
					FSType:                 "vfat",
					FSUsed:                 6329856,
					FSUsedPercent:          "6%",
					MountPoint:             "/boot/efi",
					Label:                  "UEFI",
					UUID:                   "1284-3BC2",
					PartitionTableUUID:     "341a00be-53e0-4393-91cf-ddf480890a27",
					PartitionTableType:     "gpt",
					PartitionType:          "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
					PartitionLabel:         "",
					PartitionUUID:          "bcf9f75e-f22f-44f4-910e-354119a7f260",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   111149056,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  4096,
					OptimalIO:              4096,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       31,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "nvme.1d0f-766f6c3037316139323365313432316638343766-416d617a6f6e20456c617374696320426c6f636b2053746f7265-00000001",
					Randomness:             false,
					ParentKernelName:       "nvme0n1",
					HostChannelTargetLun:   "",
					TransportType:          "nvme",
					Subsystems:             "block:nvme:pci",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
			},
		},
		{
			Name:                 "JSON - Bytes as integers",
			JSONData:             bytes.NewBuffer(alpineLsblkJSONOutput),
			Err:                  nil,
			ExpectedErrorMatcher: Not(HaveOccurred()),
			ExpectedBlockDeviceList: []BlockDevice{
				{
					Name:                   "loop0",
					KernelName:             "loop0",
					Path:                   "/dev/loop0",
					MajorMinor:             "7:0",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "squashfs",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "",
					PartitionTableType:     "",
					PartitionType:          "",
					PartitionLabel:         "",
					PartitionUUID:          "",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               true,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   25571328,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "none",
					RequestQueueSize:       128,
					Type:                   "loop",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     4096,
					DiscardMaxBytes:        4294966784,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "xvda",
					KernelName:             "xvda",
					Path:                   "/dev/xvda",
					MajorMinor:             "202:0",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "341a00be-53e0-4393-91cf-ddf480890a27",
					PartitionTableType:     "gpt",
					PartitionType:          "",
					PartitionLabel:         "",
					PartitionUUID:          "",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   8589934592,
					State:                  "Connected",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "mq-deadline",
					RequestQueueSize:       64,
					Type:                   "disk",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block:xen",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "xvda1",
					KernelName:             "xvda1",
					Path:                   "/dev/xvda1",
					MajorMinor:             "202:1",
					FSAvail:                5184663552,
					FSSize:                 8132173824,
					FSType:                 "ext4",
					FSUsed:                 2930733056,
					FSUsedPercent:          "36%",
					MountPoint:             "/var/opt/openclarity",
					Label:                  "cloudimg-rootfs",
					UUID:                   "db7f5fbc-cf4b-45ae-985d-11e4b2222934",
					PartitionTableUUID:     "",
					PartitionTableType:     "",
					PartitionType:          "0fc63daf-8483-4772-8e79-3d69d8477de4",
					PartitionLabel:         "",
					PartitionUUID:          "3a6867c7-ffb2-4db0-8246-7c2569317446",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   8473525760,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "mq-deadline",
					RequestQueueSize:       64,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "xvda",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block:xen",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "xvda14",
					KernelName:             "xvda14",
					Path:                   "/dev/xvda14",
					MajorMinor:             "202:14",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "",
					UUID:                   "",
					PartitionTableUUID:     "",
					PartitionTableType:     "",
					PartitionType:          "21686148-6449-6e6f-744e-656564454649",
					PartitionLabel:         "",
					PartitionUUID:          "53413f32-d40c-4d40-8384-c7221fa8e2c9",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   4194304,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "mq-deadline",
					RequestQueueSize:       64,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "xvda",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block:xen",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
				{
					Name:                   "xvda15",
					KernelName:             "xvda15",
					Path:                   "/dev/xvda15",
					MajorMinor:             "202:15",
					FSAvail:                0,
					FSSize:                 0,
					FSType:                 "vfat",
					FSUsed:                 0,
					FSUsedPercent:          "",
					MountPoint:             "",
					Label:                  "UEFI",
					UUID:                   "1284-3BC2",
					PartitionTableUUID:     "",
					PartitionTableType:     "",
					PartitionType:          "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
					PartitionLabel:         "",
					PartitionUUID:          "bcf9f75e-f22f-44f4-910e-354119a7f260",
					PartitionFlags:         "",
					ReadAhead:              128,
					ReadOnly:               false,
					Removable:              false,
					HotPlug:                false,
					Model:                  "",
					Serial:                 "",
					Size:                   111149056,
					State:                  "",
					Owner:                  "root",
					Group:                  "disk",
					Mode:                   "brw-rw----",
					AlignmentOffset:        0,
					MinIO:                  512,
					OptimalIO:              0,
					PhysicalSectorSize:     512,
					LogSecSectorSize:       512,
					Rotational:             false,
					Scheduler:              "mq-deadline",
					RequestQueueSize:       64,
					Type:                   "part",
					DiscardAlignmentOffset: 0,
					DiscardGranularity:     0,
					DiscardMaxBytes:        0,
					DiscardZeroesData:      false,
					WriteSameMaxBytes:      0,
					WWN:                    "",
					Randomness:             false,
					ParentKernelName:       "xvda",
					HostChannelTargetLun:   "",
					TransportType:          "",
					Subsystems:             "block:xen",
					Revision:               "",
					Vendor:                 "",
					Zoned:                  "none",
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.Name, func(t *testing.T) {
			g := NewGomegaWithT(t)

			blockDevices, err := parseJSONFormat(test.JSONData)

			g.Expect(err).Should(test.ExpectedErrorMatcher)
			for idx, dev := range blockDevices {
				g.Expect(dev).Should(BeEquivalentTo(test.ExpectedBlockDeviceList[idx]))
			}
			// g.Expect(blockDevices).Should(BeEquivalentTo(test.ExpectedBlockDeviceList))
		})
	}
}
